package damngoodcoffee.smart.interpreters;

import java.util.ArrayList;
import java.util.List;

import com.google.inject.Inject;
import com.google.inject.Provider;

import damngoodcoffee.smart.commands.Command;
import damngoodcoffee.smart.commands.GroupCommand;
import damngoodcoffee.smart.commands.SeleniumCommand;
import damngoodcoffee.smart.tags.EndTag;
import damngoodcoffee.smart.tags.StartTag;
import damngoodcoffee.smart.tags.Tag;

public class CodeInterpreter implements Interpreter {
    private GroupCommand commands = new GroupCommand();
    private List<String> queue = new ArrayList<String>();
    private Provider<SeleniumCommand> commandProvider;

    @Inject
    public CodeInterpreter(Provider<SeleniumCommand> provider) {
	commandProvider = provider;
    }

    private void createCommand(List<String> q) throws InterruptedException {
	String command = q.size() > 0 ? q.remove(0) : "";
	String target = q.size() > 0 ? q.remove(0) : "";
	String value = q.size() > 0 ? q.remove(0) : "";

	SeleniumCommand seleniumCommand = commandProvider.get();
	seleniumCommand.setCommand(command);
	seleniumCommand.setTarget(target);
	seleniumCommand.setValue(value);
	commands.add(seleniumCommand);
    }

    public Command getCommand() {
	return commands;
    }

    public void interpret(String value) {
	value = value.trim();
	if (value.length() > 0) {
	    queue.add(value);
	}
    }

    private boolean canInterpret(Tag t) {
	return t.getLocalName().equals("div");
    }

    public boolean canInterpret(EndTag t) {
	return canInterpret((Tag) t);
    }

    public void interpret(StartTag t) throws InterpreterException {
	if (t.getLocalName().equals("tr")) {
	    queue.clear();
	}
    }

    public void interpret(EndTag t) throws InterpreterException {
	if (!queue.isEmpty() && t.getLocalName().equals("tr")) {
	    try {
		createCommand(queue);
	    } catch (InterruptedException e) {
		throw new InterpreterException(e);
	    }
	}
    }

    public boolean canInterpret(StartTag t) {
	return canInterpret((Tag) t) && t.getAtts() != null
		&& t.getAtts().getValue("class") != null
		&& t.getAtts().getValue("class").equals("code");
    }

}
